/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package miagemosaik.tools;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import miagemosaik.Photo;

/**
 *
 * @author DoZ
 */
public class ImageUtils {

    public final static int MAILLE = 20;
    private static int h;
    private static int w;
    private static int nbBlocHeight;
    private static int nbBlocWidth;
    private static BufferedImage imgFinale;
    private static int cptX = 0;
    private static int cptY = 0;
    private static int stateY = 0;
    private static int stateX = 0;

    /**
     * creer l'image a afficher
     * @param mosaique
     * @return
     */
    public static Image creeImageFinale(Photo[][] mosaique, String path) {
        imgFinale = new BufferedImage(860, 640, BufferedImage.TYPE_INT_RGB);
        cptY = 0;
        cptX = 0;
        stateY = 0;
        stateX = 0;
        for (int i = 0; i < nbBlocHeight; i++) {
            for (int j = 0; j < nbBlocWidth; j++) {
                BufferedImage imgTemp = getPhotoAsImage(path + "\\" + mosaique[i][j].getName());
                updateImageFinale(imgTemp);
            }
        }
        return imgFinale;
    }

    /**permet de dessiner l'image finale
     *
     **/
    private static void updateImageFinale(BufferedImage imgTemp) {
        int indX = 0;
        int indY = 0;

        if (stateY >= imgFinale.getWidth()) {
            stateY = 0;
            cptY = 0;
            stateX += MAILLE;
            cptX = stateX;
        } else {
            cptY = stateY;
            cptX = stateX;
        }

        for (int i = cptX; (i < imgFinale.getHeight()) && (indX < MAILLE); i++) {
            for (int j = cptY; (j < imgFinale.getWidth()) && (indY < MAILLE); j++) {
                imgFinale.setRGB(j, i, imgTemp.getRGB(indY, indX));
             /*   System.out.println("i : " + i);
                 System.out.println("j : " + j);
                  System.out.println("cptX : " + cptX);
                   System.out.println("cptY : " + cptY);*/
                indY++;
            }
            indY = 0;
            indX++;
        }
        stateY += MAILLE;
    }

    /**
     * Permet de créer la mosaique d'image
     * @param colorTab
     * @return
     */
    public static Photo[][] getMosaiqueTab(Color[][] colorTab) {
        Photo[][] tab = new Photo[nbBlocHeight][nbBlocWidth];

        for (int i = 0; i < colorTab.length; i++) {
            for (int j = 0; j < colorTab[i].length; j++) {
                tab[i][j] = FileUtils.getSimilar(colorTab[i][j].getRed(), colorTab[i][j].getGreen(), colorTab[i][j].getBlue());
            }
        }
        //afficherPhotoTab(tab);
        return tab;
    }

    /**
     * Calcul de la moyenne RGB d'une image
     * @param image
     * @return moy : moyenne RGB obtenu pour l'image
     */
    public static Color moyRGB(BufferedImage bi) {

        h = bi.getHeight();
        w = bi.getWidth();
        int rgb = bi.getRGB(0, 0);
        int[] tabRGB = new int[3];

        for (int x = 0; x < h; ++x) {
            for (int y = 0; y < w; ++y) {
                rgb = bi.getRGB(x, y);
                Color couleur = new Color(rgb);
                tabRGB[0] += couleur.getRed();
                tabRGB[1] += couleur.getGreen();
                tabRGB[2] += couleur.getBlue();
            }
        }

        tabRGB[0] = (int) (tabRGB[0] / (h * w));
        tabRGB[1] = (int) (tabRGB[1] / (h * w));
        tabRGB[2] = (int) (tabRGB[2] / (h * w));

        return new Color(tabRGB[0], tabRGB[1], tabRGB[2]);
    }

    public static ImageIcon openPhoto(String path) {

        //Récupere image de fond et la retaille
        ImageIcon logo = new ImageIcon(path);
        Image logoReSize = logo.getImage().getScaledInstance(860, 640, Image.SCALE_DEFAULT);
        ImageIcon photo = new ImageIcon(logoReSize);
        return photo;
    }

    public static Color[][] getSplittedImage(BufferedImage img) {
        h = img.getHeight();
        w = img.getWidth();

        if (img.getHeight() < MAILLE || img.getWidth() < MAILLE) {
            throw new IllegalArgumentException("maillage trop élevé pour la taille de l'image");
        }

        nbBlocHeight = (int) (Math.ceil((double) (img.getHeight() / MAILLE)));
        nbBlocWidth = (int) (Math.ceil((double) (img.getWidth() / MAILLE)));

        Color[][] imageFinale = new Color[nbBlocHeight][nbBlocWidth];

        for (int i = 0; i < nbBlocHeight; i++) {
            for (int j = 0; j < nbBlocWidth; j++) {
                imageFinale[i][j] = initCurrentBloc(i, j, img);
            }
        }
        //  afficherTabColor(imageFinale);
        return imageFinale;
    }

    private static Color initCurrentBloc(int i, int j, BufferedImage img) {

        // creer la miniature de 20x20 (par defaut)
        BufferedImage imgTemp = new BufferedImage(MAILLE, MAILLE, BufferedImage.TYPE_INT_RGB);

        int ctrX = 0;
        int ctrY = 0;

        for (int k = MAILLE * i; (k < img.getHeight()) && ctrX < MAILLE; k++) {
            for (int l = MAILLE * j; (l < img.getWidth()) && ctrY < MAILLE; l++) {
                try {
                    imgTemp.setRGB(ctrX, ctrY, img.getRGB(l, k));
                    ctrY++;
                } catch (ArrayIndexOutOfBoundsException e) {
                    e.printStackTrace();
                }
            }
            ctrY = 0;
            ctrX++;
        }
        Color colorMoyenne = ImageUtils.moyRGB(imgTemp);
        return colorMoyenne;
    }

    private static BufferedImage getPhotoAsImage(String path) {
        ImageIcon icon = new ImageIcon(path);
        BufferedImage image = new BufferedImage(
                icon.getIconWidth(),
                icon.getIconHeight(),
                BufferedImage.TYPE_INT_RGB);
        Graphics2D graph = image.createGraphics();
        graph.drawImage(icon.getImage(), 0, 0, null);
        graph.dispose();

        return image;
    }

    private static void afficherPhotoTab(Photo[][] tab) {
        System.out.println(tab.length);
        System.out.println(tab[0].length);
        for (int i = 0; i < tab.length; i++) {
            for (int j = 0; j < tab[i].length; j++) {
                System.out.print(tab[i][j]);
            }
            System.out.println("\n");
        }
    }

    private static void afficherTabColor(Color[][] tab) {
        System.out.println(tab.length);
        System.out.println(tab[0].length);
        for (int i = 0; i < tab.length; i++) {
            for (int j = 0; j < tab[i].length; j++) {
                System.out.print(tab[i][j].getRed() + "\t" + tab[i][j].getGreen() + "\t" + tab[i][j].getBlue() + "\t");
            }
            System.out.println("\n");
        }
    }

    public static void saveImage(String path, ImageIcon buff) throws FileNotFoundException, IOException {

        FileOutputStream fos = new FileOutputStream(path);

        BufferedImage image = new BufferedImage(
                buff.getIconWidth(),
                buff.getIconHeight(),
                BufferedImage.TYPE_INT_RGB);
        Graphics2D graph = image.createGraphics();
        graph.drawImage(buff.getImage(), 0, 0, null);
        graph.dispose();
        ImageIO.write(image, "jpg", fos);
        fos.close();

        System.out.println("image sauvegardée ");
    }
}
